import requests
import time
import logging
from typing import Dict, Optional, List
from requests.exceptions import RequestException

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)


class SteamAPIClient:
    """
    Steam API客户端类，负责处理与Steam API的通信
    """

    def __init__(self, base_url: str = "https://store.steampowered.com/api/featuredcategories",
                 retries: int = 3,
                 timeout: int = 30,
                 proxies: Optional[Dict[str, str]] = None):
        """
        初始化Steam API客户端

        Args:
            base_url: API的基础URL
            retries: 请求失败时的重试次数
            timeout: 请求超时时间（秒）
            proxies: 代理设置，例如 {'http': 'http://127.0.0.1:7890', 'https': 'http://127.0.0.1:7890'}
        """
        self.base_url = base_url
        self.retries = retries
        self.timeout = timeout
        self.session = requests.Session()
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
            'Accept': 'application/json',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
        }
        self.session.headers.update(self.headers)

        # 设置代理
        if proxies:
            self.session.proxies.update(proxies)
            logger.info(f"已设置代理: {proxies}")

    def fetch_top_sellers(self) -> List[Dict]:
        """
        获取Steam畅销游戏排行榜数据

        Returns:
            List[Dict]: 包含畅销游戏信息的列表
        """
        try:
            data = self.fetch_data()
            if 'top_sellers' in data:
                items = data['top_sellers']['items']
                # 处理价格数据
                for item in items:
                    # 处理价格数据
                    if 'final_price' in item:
                        # 价格以分为单位，需要转换为元
                        item['price'] = item['final_price'] / 100
                    else:
                        item['price'] = 0.0
                    
                    # 处理折扣数据
                    if 'discount_percent' in item:
                        item['discount'] = item['discount_percent']
                    else:
                        item['discount'] = 0
                return items
            return []
        except Exception as e:
            logger.error(f"获取畅销游戏数据失败: {str(e)}")
            return []

    def fetch_data(self) -> Dict:
        """
        获取Steam游戏数据

        Returns:
            Dict: 包含游戏数据的字典

        Raises:
            RequestException: 当所有重试都失败时抛出
        """
        for attempt in range(self.retries):
            try:
                response = self._make_request()
                return self._handle_response(response)
            except RequestException as e:
                self._handle_error(e)
                if attempt == self.retries - 1:
                    raise
                wait_time = 2 ** attempt  # 指数退避
                logger.info(f"第{attempt + 1}次重试失败，等待{wait_time}秒后重试...")
                time.sleep(wait_time)
        return {}

    def _make_request(self) -> requests.Response:
        """
        发送HTTP请求

        Returns:
            requests.Response: 响应对象

        Raises:
            RequestException: 当请求失败时抛出
        """
        try:
            logger.info(f"正在请求URL: {self.base_url}")
            response = self.session.get(self.base_url, timeout=self.timeout)
            response.raise_for_status()
            return response
        except RequestException as e:
            logger.error(f"请求失败: {str(e)}")
            raise

    def _handle_response(self, response: requests.Response) -> Dict:
        """
        处理API响应

        Args:
            response: 响应对象

        Returns:
            Dict: 处理后的数据

        Raises:
            ValueError: 当响应数据格式不正确时抛出
        """
        try:
            data = response.json()
            if not isinstance(data, dict):
                raise ValueError("响应数据格式不正确")
            logger.info("成功获取数据")
            return data
        except ValueError as e:
            logger.error(f"响应处理失败: {str(e)}")
            raise

    def _handle_error(self, error: Exception) -> None:
        """
        错误处理

        Args:
            error: 错误对象
        """
        logger.error(f"发生错误: {str(error)}")
        if isinstance(error, requests.exceptions.Timeout):
            logger.warning("请求超时")
        elif isinstance(error, requests.exceptions.HTTPError):
            logger.warning(f"HTTP错误: {error.response.status_code}")
        elif isinstance(error, requests.exceptions.ConnectionError):
            logger.warning("连接错误")
        elif isinstance(error, requests.exceptions.RequestException):
            logger.warning("请求异常")


def print_top_sellers(top_sellers: List[Dict]) -> None:
    """
    打印畅销游戏信息

    Args:
        top_sellers: 畅销游戏列表
    """
    print("\nSteam畅销游戏排行榜：")
    print("-" * 80)
    print(f"{'排名':<6}{'游戏名称':<40}{'价格':<15}{'折扣':<10}")
    print("-" * 80)
    
    for idx, game in enumerate(top_sellers, 1):
        name = game.get('name', '未知游戏')
        price = game.get('final_price', 0) / 100  # 转换为元
        discount = game.get('discount_percent', 0)
        
        # 格式化输出
        print(f"{idx:<6}{name:<40}{f'¥{price:.2f}':<15}{f'-{discount}%':<10}")


if __name__ == "__main__":
    # 测试代码
    # 如果需要使用代理，请取消下面注释并设置正确的代理地址
    proxies = {
      'http': 'http://127.0.0.1:7890',
        'https': 'http://127.0.0.1:7890'
    }
    client = SteamAPIClient(proxies=proxies)

    client = SteamAPIClient()
    try:
        top_sellers = client.fetch_top_sellers()
        print_top_sellers(top_sellers)
    except Exception as e:
        print(f"发生错误: {str(e)}")